package br.com.bankai.koby.repository.impl;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import br.com.bankai.koby.repository.entity.Usuario;
import br.com.bankai.koby.repository.entity.simple.UsuarioSimple;
import br.com.graflogic.utilities.datautil.repository.BaseRepository;

/**
 * 
 * @author Leonardo
 *
 */
@Repository
public class UsuarioRepository extends BaseRepository<Usuario> {

	public UsuarioRepository() {
		super(Usuario.class);
	}

	public List<UsuarioSimple> search(UsuarioSimple entity, List<String> papeis) {
		CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
		CriteriaQuery<UsuarioSimple> query = builder.createQuery(UsuarioSimple.class);
		List<Predicate> predicateList = new ArrayList<Predicate>();

		Root<UsuarioSimple> usuario = query.from(UsuarioSimple.class);

		if (StringUtils.isNotEmpty(entity.getCpf())) {
			predicateList.add(builder.and(builder.like(usuario.<String> get("cpf"), "%" + entity.getCpf() + "%")));
		}

		if (StringUtils.isNotEmpty(entity.getNome())) {
			predicateList.add(builder.and(builder.like(builder.upper(usuario.<String> get("nome")), "%" + entity.getNome().toUpperCase() + "%")));
		}

		if (null != papeis && !papeis.isEmpty()) {
			predicateList.add(builder.in(usuario.get("codigoPapel")).value(papeis));
		}

		predicateList.add(builder.and(builder.equal(usuario.get("tipo"), entity.getTipo())));

		query.where(predicateList.toArray(new Predicate[predicateList.size()]));
		query.orderBy(builder.asc(usuario.get("nome")));
		TypedQuery<UsuarioSimple> typedQuery = getEntityManager().createQuery(query);

		return typedQuery.getResultList();
	}

	public UsuarioSimple find(UsuarioSimple entity) {
		CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
		CriteriaQuery<UsuarioSimple> query = builder.createQuery(UsuarioSimple.class);
		List<Predicate> predicateList = new ArrayList<Predicate>();

		Root<UsuarioSimple> usuario = query.from(UsuarioSimple.class);

		if (StringUtils.isNotEmpty(entity.getCpf())) {
			predicateList.add(builder.and(builder.equal(usuario.get("cpf"), entity.getCpf())));
		} else {
			predicateList.add(builder.and(builder.equal(usuario.get("id"), entity.getId())));
		}

		if (StringUtils.isNotEmpty(entity.getTipo())) {
			predicateList.add(builder.and(builder.equal(usuario.get("tipo"), entity.getTipo())));
		}
		query.where(predicateList.toArray(new Predicate[predicateList.size()]));
		TypedQuery<UsuarioSimple> typedQuery = getEntityManager().createQuery(query);

		return typedQuery.getSingleResult();
	}

	public Usuario find(Usuario entity) {
		CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
		CriteriaQuery<Usuario> query = builder.createQuery(Usuario.class);
		List<Predicate> predicateList = new ArrayList<Predicate>();

		Root<Usuario> usuario = query.from(Usuario.class);

		if (StringUtils.isNotEmpty(entity.getCpf())) {
			predicateList.add(builder.and(builder.equal(usuario.get("cpf"), entity.getCpf())));
		} else {
			predicateList.add(builder.and(builder.equal(usuario.get("id"), entity.getId())));
		}

		if (StringUtils.isNotEmpty(entity.getTipo())) {
			predicateList.add(builder.and(builder.equal(usuario.get("tipo"), entity.getTipo())));
		}

		query.where(predicateList.toArray(new Predicate[predicateList.size()]));
		TypedQuery<Usuario> typedQuery = getEntityManager().createQuery(query);

		return typedQuery.getSingleResult();
	}
	
	
	@Transactional
	public void updateQuantidadeTentativas(Long idUsuario, int quantidadeTentativas) {
		String queryStr = "UPDATE tb_usuario SET qt_tentativa = " + quantidadeTentativas + " WHERE id_pessoa = " + idUsuario;

		getEntityManager().createNativeQuery(queryStr).executeUpdate();
	}

	@Transactional
	public void updateSenhaAcesso(Long idUsuario, String senhaAcesso) {
		String queryStr = "UPDATE tb_usuario SET sn_acesso = '" + senhaAcesso + "' WHERE id_pessoa = " + idUsuario;

		getEntityManager().createNativeQuery(queryStr).executeUpdate();
	}

	@Transactional
	public void updateStatus(Long idUsuario, char status) {
		String queryStr = "UPDATE tb_pessoa SET cd_status = " + status + " WHERE id_pessoa = " + idUsuario;

		getEntityManager().createNativeQuery(queryStr).executeUpdate();
	}

}
